home *** CD-ROM | disk | FTP | other *** search
- TITLE LS - SORTED DIRECTORY PROGRAM
- PAGE 55,132
- ;************************************************************************
- ; THIS PROGRAM DISPLAYS A SORTED DIRECTORY WITH FILE SIZES.
- ; IT REQUIRES MSDOS VERSION 2 OR HIGHER.
- ;
- ; usage: LS/A/L afn
- ; /A (optional) includes hidden and system files
- ; /L (optional) shows date, time, file size in bytes
- ; afn may contain * and ?: e.g. "LS PROG?.*"
- ;
- ; BY: JON DART
- ; DEPARTMENT OF ANTHROPOLOGY
- ; UCSD C-001
- ; LA JOLLA, CA 92093
- ;
- ; Version 1.6, 05-Jul-86 fixes sometime loss of top display line.
- ; Now accepts - as well as / for switches.
- ; Also modified to assemble under MASM 4.0.
- ; Version 1.5, 04-May-86 fixes clear screen routine
- ; Version 1.4, 17-Jan-86 UTIL and CONSOLE made external modules,
- ; adds FIXPATH function
- ; Version 1,3, 07-Nov-85 /L option added
- ; Version 1.2, 03-Nov-85 fixes bug in size function
- ; Version 1.1, 18-Oct-85
- ;
- ; TO BUILD LS.EXE:
- ; MASM LS,LS,NUL,NUL
- ; LINK LS,LS,NUL,ASM -C1200 -DO
-
- IF2
- %OUT PASS 2
- ENDIF
-
- TRUE EQU 1
- FALSE EQU 0
- IBM EQU TRUE ;TRUE IF IBM-COMPATIBLE AT BIOS LEVEL
- BIOS EQU 10H ;BIOS INTERRUPT FOR VIDEO FUNCTIONS
- MAXFILES EQU 512 ;MAX # OF FILES
- NCOLUMN EQU 4 ;# OF COLUMNS TO DISPLAY (SHORT MODE)
- MAXLINES EQU 23 ;# LINES ON SCREEN FOR FILE DISPLAY
- IF IBM
- FENCE EQU 179 ;VERTICAL BAR CHAR. (IBM ONLY)
- ELSE
- FENCE EQU '|' ;BORDER BETWEEN COLUMNS
- ENDIF
- K EQU 1024 ;1 K
-
- M EQU BYTE PTR 0[BX]
-
- .XLIST
- INCLUDE ASCII.DEF
- INCLUDE MSDOS2.DEF
- INCLUDE MACROS.DEF
- .LIST
-
- SETDS MACRO
- PUSH DS
- PUSH AX
- MOV AX,DATA
- MOV DS,AX
- POP AX
- ENDM
-
- RESDS MACRO
- POP DS
- ENDM
-
- PRINT MACRO DATA
- SETDS
- MOV DX,OFFSET DATA
- MOV AH,CON_STRING_OUTPUT
- INT DOS
- RESDS
- ENDM
-
- ; DEFINE OFFSETS OF BUFFER AREAS (FROM ES):
-
- FILNAM EQU 0 ;FILE NAME FROM COMMAND LINE
- SPATH EQU FILNAM+80 ;SEARCH PATH
- SPREFIX EQU SPATH+80 ;SEARCH PREFIX (NOT USED)
- OUR_DTA EQU SPREFIX+80 ;DISK TRANSFER ADDRESS, USED BY MSDOS
- ;FUNCTIONS 4EH AND 4FH.
- ADDRLIST EQU OUR_DTA+80H ;HOLDS POINTERS TO INFO ON EACH FILE
- BUFFER EQU ADDRLIST+(2*MAXFILES) ;HOLDS INFO ON EACH FILE, RETURNED BY
- ;MSDOS FUNCTION 4EH OR 4FH.
- ENDBUF EQU BUFFER+(MAXFILES*22)
-
- STACK SEGMENT WORD STACK 'STACK'
- DB 512 DUP (?)
- STACK ENDS
-
- ;*********************
- ; MEMORY DEFINITIONS *
- ;*********************
- ;
- DATA SEGMENT BYTE PUBLIC 'DATA'
- AFLAG DB 0 ;SET <>0 IF /A
- LFLAG DB 0 ;SET <>0 IF /L
- DRIVE DB 0 ;DRIVE (0 FOR DEFAULT, 1 FOR A, ETC)
- VPAGE DB 0 ;VIDEO PAGE # (IBM ONLY)
- SCRSIZE DB 80 ;SCREEN WIDTH (80 IS DEFAULT FOR NON-IBM)
- VMODE DB 0 ;DISPLAY MODE (IBM ONLY)
- ATTRIBUTES DB 00010001B ;DEFAULT FILE ATTRIBUTES
- NUMFILES DW 0 ;NUMBER OF FILES FOUND
- NEXTFREE DW 1 DUP (?) ;ADDR. OF NEXT FREE SLOT IN BUFFER
- GAP DW 0 ;USED BY SORT ROUTINE
- TEMP DW 0 ;USED BY SORT ROUTINE
- MAXLINE DW 1 DUP (?) ;NO. OF LINES TO DISPLAY
- MAXFILE DW 1 DUP (?) ;MAX FILE TO SHOW
- MAXCOL DB 1 DUP (?) ;COLUMN WIDTH OF DISPLAY
- COLCOUNT DW 1 DUP (?) ;COUNT OF COLUMNS DISPLAYED
- LINECOUNT DW 1 DUP (?) ;COUNT OF LINES DISPLAYED
- FILECOUNT DW 1 DUP (?) ;COUNT OF FILES DISPLAYED
- BASE DW 1 DUP (?) ;FIRST FILE TO SHOW
- USED DQ 0 ;COUNT OF FILE SPACE USED
- DEFAULT DB '????????.???',0 ;DEFAULT FILE NAME
- LOSIZE DW 1 DUP (?) ;USED IN CALCULATING FREE SPACE
- MSG1 DB CR,LF,'Bad switch: '
- BADSW DB 1 DUP (?)
- DB CR,LF,'$'
- MSG2 DB CR,LF,'No matching files.',CR,LF,'$'
- MSG3 DB '[ More ] ','$'
- MSG4 DB CR,LF,'Not enough memory for buffers',CR,LF,'$'
- DATA ENDS
-
- CODE SEGMENT BYTE PUBLIC
- ASSUME CS:CODE,DS:DATA,SS:STACK
- EXTRN SKIPSP:NEAR,UC:NEAR,DECOUT:NEAR,CPYCNT:NEAR,CPY:NEAR
- EXTRN ERRORMSG:NEAR
- EXTRN TYPTX:NEAR
- EXTRN PRINTDD:NEAR
- EXTRN COUT:NEAR,CIN:NEAR,CLRCO:NEAR,CRLF:NEAR
- EXTRN FIXPATH:NEAR
-
- ;*********************
- ; START OF CODE HERE *
- ;*********************
-
- ENTRY:
- TEST_DOS2 ;TEST FOR DOS 2.0, EXIT IF DOS 1
- CALL ALLOC_MEM ;ALLOCATE MEMORY
- CALL PARSE_LINE ;PARSE COMMAND LINE
- CALL FIND_FILES ;SEARCH FOR FILES, BUILD LIST IN MEMORY
- CALL SORT_FILES ;SORT FILE LIST
- CALL SHOW_FILES ;DISPLAY DIRECTORY
- CALL SHOW_INFO ;SHOW DISK USAGE INFO
- MOV AH,EXIT
- INT DOS ;EXIT TO DOS
-
- ;*****************************************************
- ; ALLOCATE MEMORY FOR BUFFERS, SET ES TO POINT TO IT *
- ;*****************************************************
-
- ALLOC_MEM PROC NEAR
- MOV AX,DS
- MOV ES,AX
- MOV BX,((1000H+ENDBUF) SHR 4)+1 ;RESERVE SPACE FOR PROGRAM+BUFFERS
- MOV AH,SET_BLOCK
- INT DOS
- JB NOROOM ;IF ERROR
- MOV AX,DS ;GET DATA SEG
- ADD AX,1000H ;ADD OFFSET TO BUFFER AREA
- MOV ES,AX ;SET EXTRA SEG TO POINT TO BUFFERS
- RET
- NOROOM: MOV AX,DATA ;NOT ENOUGH MEMORY
- MOV DS,AX
- PRINT MSG4 ;PRINT MSG
- MOV AH,EXIT
- INT DOS ;EXIT 2 DOS
- ALLOC_MEM ENDP
-
- ;***************************************************
- ; PARSE COMMAND LINE AND BUILD SEARCH PATH IN SPATH*
- ;***************************************************
-
- PARSE_LINE PROC NEAR
- MOV BX,OFFSET (80H) ;POINT TO BYTE COUNT FOR COMMAND LINE
- CMP BYTE PTR [BX],0 ;FETCH IT
- JNZ L_1 ;IF SOMETHING ON COMMAND LINE
- JMP NONAME
- L_1:
- PUSH BX
- MOV DL,M
- MOV DH,0
- ADD BX,DX
- INC BX
- MOV M,0 ;PUT 0 BYTE AT END OF COMMAND LINE
- POP BX
- SWLOOP:
- INC BX
- CALL SKIPSP ;SKIP LEADING BLANKS
- JB NOSWITCH
- MOV AL,M ;GET 1ST CHAR.
- CMP AL,'/' ;SWITCH SPECIFIED?
- JE GOTSW ;YES
- CMP AL,'-' ;CHECK FOR HYPHEN, TOO
- JNE NOSWITCH
- GOTSW: INC BX
- MOV AL,M ;GET CHAR. AFTER SWITCH
- CALL UC ;MAKE UPPER-CASE
- CMP AL,'A' ;CHECK FOR A
- JE ASWITCH ;IF GOT A
- CMP AL,'L' ;CHECK FOR L
- JE LSWITCH ;IF GOT L
- BADSWITCH:
- SETDS ;COME HERE IF BAD SWITCH FOUND
- MOV BYTE PTR BADSW,AL
- PRINT MSG1 ;GIVE BAD SWITCH MSG.
- RESDS
- MOV AH,EXIT ;EXIT TO DOS
- INT DOS
- ASWITCH:
- SETDS
- MOV BYTE PTR AFLAG,0FFH ;SET A FLAG
- RESDS
- JMP SWLOOP ;CHECK FOR ANOTHER SWITCH
- LSWITCH:
- SETDS
- MOV BYTE PTR LFLAG,0FFH ;SET L FLAG
- RESDS
- JMP SWLOOP ;CHECK FOR ANOTHER SWITCH
-
- NOSWITCH:
- CALL SKIPSP ;SKIP LEADING BLANKS
- JNC GOTNAME ;IF SOMETHING ON COMMAND LINE
- MOV AX,DATA
- MOV DS,AX
- MOV BX,OFFSET DEFAULT ;NO NAME SPECIFIED, POINT TO DEFAULT
- JMP SHORT COPYNAME ;COPY INTO FILE NAME BUFFER
- GOTNAME:
- MOV AL,[BX+1] ;SEE IF DRIVE SPECIFIED
- CMP AL,':'
- JNE NODRIVE ;IF NOT
- MOV AL,[BX+0] ;GET DRIVE LETTER
- CALL UC ;MAKE UPPER-CASE
- SETDS
- MOV BYTE PTR ES:FILNAM,AL ;SAVE DRIVE LETTER IN FILE NAME BUFFER
- MOV BYTE PTR ES:(FILNAM+1),':' ;SAVE COLON ALSO
- SUB AL,'A'-1 ;CONVERT ASCII TO BINARY (A=1, ETC.)
- MOV BYTE PTR DRIVE,AL ;SAVE BINARY DRIVE
- RESDS
- INC BX ;SKIP OVER DRIVE
- INC BX ;AND COLON
- CALL SKIPSP ;ANYTHING AFTER DRIVE SPEC?
- MOV SI,BX ;SAVE START OF FILE NAME, JUST IN CASE
- JNB DRVPLUSFILE ;IF FILE NAME GIVEN, COPY INTO NAME BUFFER
- MOV AX,DATA
- MOV DS,AX
- MOV SI,OFFSET DEFAULT ;ELSE SI POINTS TO DEFAULT FILE NAME
- DRVPLUSFILE:
- MOV DI,OFFSET FILNAM+2 ;DI POINTS TO DESTINATION
- JMP SHORT COPYNAME2 ;GO COPY FILENAME TO FILE BUFFER
- NONAME: MOV AX,DATA ;IF NO NAME, JUST COPY DEFAULT TO FILNAM
- MOV DS,AX
- MOV SI,OFFSET DEFAULT
- MOV DI,OFFSET FILNAM
- JMP SHORT COPYNAME2
- NODRIVE:
- COPYNAME:
- MOV SI,BX ;DS:SI POINTS TO START OF NAME
- MOV DI,OFFSET FILNAM
- COPYNAME2:
- MOV CX,80
- CALL CPYCNT ;SAVE FILE NAME
- PUSH DS
- MOV AX,ES
- MOV DS,AX ;MAKE DATA SEG POINT TO BUFFER AREAS
- MOV BX,OFFSET FILNAM ;BX - FILE NAME
- MOV CX,OFFSET SPATH ;CX - STORAGE FOR SEARCH PATH
- MOV DX,OFFSET SPREFIX ;DX - STORAGE FOR SEARCH PREFIX (NOT USED)
- CALL FIXPATH ;PARSE FILE NAME
- POP DS
- RET
- NOFILE:
- PRINT MSG2
- MOV AH,EXIT
- INT DOS
- PARSE_LINE ENDP
-
- ;**********************
- ; FILE SEARCH ROUTINE *
- ;**********************
- FIND_FILES PROC NEAR
- SETDTA:
- MOV AX,ES
- MOV DS,AX ;SET DS=ES (WHERE DTA BUFFER IS)
- MOV DX,OFFSET OUR_DTA ;LOAD ITS OFFSET
- MOV AH,SET_DTA
-
- INT DOS ;SET UP DTA
- MOV AX,DATA
- MOV DS,AX ;RESET DATA SEG.
- MOV CX,WORD PTR ATTRIBUTES ;GET DEFAULT ATTRIBUTES
- CMP BYTE PTR AFLAG,0 ;A FLAG SET?
- JE SHORT NOAFLAG ;NO
- OR CX,00000110B ;YES, SET SYSTEM & HIDDEN ATTRIBUTES
- NOAFLAG:
- ;***********************
- ; SEARCH FOR 1ST MATCH *
- ;***********************
- PUSH DS
- MOV AX,ES
- MOV DS,AX ;MAKE DATA SEG = BUFFER SEG
- MOV DX,OFFSET SPATH ;POINT TO SEARCH PATH
- MOV AH,FIND_FIRST
- INT DOS ;SEARCH FOR 1ST MATCH
- POP DS
- JNC FOUND1ST ;IF FOUND
- JMP NOFILE
- ;*********************************************************************
- ; COLLECT FILE INFO BLOCKS IN BUFFER, POINTERS TO BLOCKS IN ADDRLIST *
- ;*********************************************************************
- FOUND1ST:
- MOV AX,OFFSET BUFFER
- MOV WORD PTR NEXTFREE,AX
- FOUND1: INC WORD PTR NUMFILES
- CMP WORD PTR NUMFILES,MAXFILES
- JGE LASTFILE
- MOV DI,WORD PTR NEXTFREE
- PUSH DI
- PUSH DS
- MOV AX,ES
- MOV DS,AX ;SET DATA SEG = EXTRA SEG
- MOV SI,OUR_DTA+21
- MOV CX,22
- CALL CPY ;COPY FILE INFO TO TABLE
- POP DS ;RESTORE DS
- ADD WORD PTR NEXTFREE,22
- MOV AX,NUMFILES
- ADD AX,AX
- ADD AX,OFFSET ADDRLIST
- MOV SI,AX
- POP BX
- MOV ES:[SI],BX ;STORE ADDR IN LIST
- MOV AH,FIND_NEXT
- INT DOS ;FIND NEXT FILE
- JNC FOUND1 ;LOOP UNTIL NO MORE
- LASTFILE:
- RET
- FIND_FILES ENDP
-
- ;********************************************************
- ; SORT POINTERS IN ADDRLIST, USING SHELL SORT ALGORITHM *
- ;********************************************************
- SORT_FILES PROC NEAR
- MOV AX,WORD PTR NUMFILES
- SORT1:
- SHR AX,1
- MOV WORD PTR GAP,AX
- JNZ SHORT SORT11
- RET ;DONE IF GAP = 0
- SORT11:
- INC AX
- MOV BX,AX
- SORT2: CMP BX,WORD PTR NUMFILES
- JG SHORT SORT5
- MOV CX,BX
- SORT3:
- MOV DX,CX
- SUB CX,WORD PTR GAP
- JBE SHORT SORT4
- CALL COMPARE ;COMPARE ADDRLIST[DX], ADDRLIST[CX]
- JLE SHORT SORT4
- CALL SWAP
- JMP SORT3
- SORT4:
- INC BX
- JMP SORT2
- SORT5:
- MOV AX,WORD PTR GAP
- JMP SORT1
- SORT_FILES ENDP
-
- COMPARE PROC NEAR
- PUSH BX
- PUSH CX
- PUSH DS
- MOV AX,ES
- MOV DS,AX
- MOV SI,CX
- ADD SI,SI
- ADD SI,OFFSET ADDRLIST
- MOV AX,ES:[SI]
- ADD AX,9
- MOV SI,AX
- MOV DI,DX
- ADD DI,DI
- ADD DI,OFFSET ADDRLIST
- MOV AX,ES:[DI]
- ADD AX,9
- MOV DI,AX
- MOV CX,11
- REPE CMPSB
- POP DS
- POP CX
- POP BX
- RET
- COMPARE ENDP
-
- SWAP PROC NEAR
- PUSH BX
- MOV SI,CX
- ADD SI,SI
- ADD SI,OFFSET ADDRLIST
- MOV BX,ES:[SI]
- MOV DI,DX
- ADD DI,DI
- ADD DI,OFFSET ADDRLIST
- MOV AX,ES:[DI]
- MOV ES:[SI],AX
- MOV ES:[DI],BX
- POP BX
- RET
- SWAP ENDP
-
- ;********************
- ; DISPLAY DIRECTORY *
- ;********************
- SHOW_FILES PROC NEAR
- IF IBM
- MOV AH,15
- INT BIOS ;GET VIDEO MODE
- MOV BYTE PTR VPAGE,BH ;STORE VIDEO PAGE #
- MOV BYTE PTR SCRSIZE,AH ;STORE CHARS/LINE
- MOV BYTE PTR VMODE,AL ;STORE DISPLAY MODE
- ENDIF
- MOV SI,OFFSET ADDRLIST
- MOV WORD PTR BASE,1
- MOV BYTE PTR MAXCOL,NCOLUMN ;INITIALIZE MAXCOL FOR SHORT DISPLAY
- CMP BYTE PTR LFLAG,0 ;LONG DISPLAY FLAG SET?
- JE DISP1 ;NO, KEEP MAXCOL INTACT
- MOV BYTE PTR MAXCOL,2 ;YES, USE 2 COLUMNS
- DISP1:
- MOV BL,BYTE PTR MAXCOL
- MOV AL,MAXLINES
- MUL BL ;COMPUTE (MAXLINES)*MAXCOL
- ADD AX,WORD PTR BASE ;ADD BASE TO GET LAST FILE # WE
- ;CAN SHOW ON THIS SCREEN
- MOV BX,AX
- MOV AX,WORD PTR NUMFILES ;COMPARE WITH TOTAL # FILES
- SUB AX,BASE ;-BASE
- INC AX ;+1
- CMP AX,BX ;WILL ALL FILES FIT ON SCREEN?
- JG DISP3 ;NO
- MOV BL,BYTE PTR MAXCOL
- DIV BL ;YES, COMPUTE # OF LINES/COLUMN
- CMP AH,0 ;IS REMAINDER 0?
- JE DISP2 ;YES, SKIP AHEAD
- INC AL ;NO, ADD 1 TO LINE COUNT
- DISP2: MOV AH,0 ;ZERO HI BYTE OF LINES/COLUMN
- MOV WORD PTR MAXLINE,AX ;MAXLINE=# OF LINES TO SHOW IN
- ;THIS SCREEN
- MOV AX,WORD PTR NUMFILES ;NUMBER OF FILES THERE ARE
- MOV WORD PTR MAXFILE,AX ;=LAST FILE # TO DISPLAY
- JMP SHORT DISP4
- DISP3: MOV AX,MAXLINES ;TOO MANY FILES FOR 1 SCREEN, SO
- MOV WORD PTR MAXLINE,AX ;USE WHOLE SCREEN FOR DISPLAY
- MOV AL,MAXLINES
- MOV BL,BYTE PTR MAXCOL
- MUL BL ;COMPUTE MAX. FILES/SCREEN
- MOV WORD PTR MAXFILE,AX ;STORE AS # OF FILES TO SHOW
- DISP4:
- MOV WORD PTR COLCOUNT,1 ;START AT COLUMN 1
- MOV WORD PTR LINECOUNT,1 ;AND LINE 1
- MOV WORD PTR FILECOUNT,0 ;# OF FILES DISPLAYED IN THIS SCREEN
- DISP5:
- MOV CX,1 ;CX WILL COUNT UP TO COLCOUNT
- MOV BX,0 ;BX WILL HOLD (CX-1)*MAXLINE
- DISP6: ;COMPUTE (COLCOUNT-1)*MAXLINE
- CMP CX,WORD PTR COLCOUNT
- JGE DISP7
- ADD BX,WORD PTR MAXLINE
- INC CX
- JMP DISP6
- DISP7:
- ADD BX,WORD PTR LINECOUNT ;ADD LINE COUNT
- DEC BX ;-1
- ADD BX,BASE ;ADD TO BASE
- CMP BX,WORD PTR NUMFILES ;BLANK SLOT IN LAST COLUMN?
- JG DISP9 ;YUP.
- CMP WORD PTR COLCOUNT,1 ;1ST COLUMN?
- JE DISP8 ;YES, NO FENCE
- CALL DOFENCE ;SHOW FENCE
- DISP8:
- ADD BX,BX ;DOUBLE FILE # TO GET OFFSET TO ADDR.
- ;OF FILE INFO
- MOV DI,ES:[SI+BX] ;GET ADDRESS OF FILE INFO
- CALL SHOW ;SHOW A FILE
- CALL BUMPCOL ;UPDATE LINE & COLUMN COUNTS
- INC WORD PTR FILECOUNT ;BUMP FILE COUNT
- MOV AX,WORD PTR FILECOUNT ;GET IT
- CMP AX,WORD PTR MAXFILE ;DONE ALL FILES?
- JGE DISP11 ;IF DONE
- JMP SHORT DISP10
- DISP9:
- CALL BUMPCOL
- DISP10:
- MOV AX,WORD PTR LINECOUNT ;GET LINE COUNT
- CMP AX,WORD PTR MAXLINE ;IS IT >MAX LINE?
- JLE DISP5 ;IF NOT
-
- ; COME HERE WHEN SCREEN IS FULL OR ALL FILES DONE:
- DISP11:
- CMP WORD PTR COLCOUNT,1 ;IS COLUMN COUNT =1?
- JLE NOADDCR ;YES, NO CR NEEDED
- CALL CRLF ;NO, SHOW CR AFTER LAST LINE
- NOADDCR:
- MOV AX,WORD PTR BASE
- ADD AX,WORD PTR MAXFILE
- MOV WORD PTR BASE,AX ;GET BASE FOR NEXT SCREEN
- MOV BX,AX
- MOV AX,WORD PTR NUMFILES
- SUB AX,BX ;COMPUTE # FILES REMAINING
- JBE ENDDISP ;IF NO MORE
- CALL WAITCR ;WAIT FOR USER
- JMP DISP1 ;DO NEXT SCREEN
- ENDDISP:
- CMP WORD PTR LINECOUNT,MAXLINES-1 ;IS SCREEN FULL (OR NEARLY SO)?
- JL NOWAIT
- CALL WAITCR ;YES, WAIT (SO INFO LINE DOESN'T CAUSE
- ;LOSS OF TOP DISPLAY LINE)
- NOWAIT:
- RET
- SHOW_FILES ENDP
-
- BUMPCOL PROC NEAR
- INC WORD PTR COLCOUNT ;BUMP COLUMN COUNT
- MOV AX,WORD PTR COLCOUNT
- CMP AL,BYTE PTR MAXCOL ;PAST LAST COLUMN?
- JLE BC1 ;NO, KEEP GOING
- CALL CRLF ;YES, START NEW LINE
- MOV WORD PTR COLCOUNT,1 ;RESET COLUMN COUNTER
- INC WORD PTR LINECOUNT ;UPDATE LINE COUNTER
- BC1:
- RET
- BUMPCOL ENDP
-
- DOFENCE PROC NEAR ;SHOW "FENCE" BETWEEN COLUMNS
- CMP BYTE PTR LFLAG,0 ;L FLAG SET?
- JE SHORTFENCE ;NO.
- CALL TYPTX ;YES, LONGER GAP BTWN. COLUMNS
- DB SPACE,SPACE+200Q
- MOV AX,FENCE
- CALL COUT
- CALL TYPTX
- DB SPACE,SPACE+200Q
- RET
- SHORTFENCE:
- MOV AX,SPACE
- CALL COUT
- MOV AX,FENCE
- CALL COUT
- MOV AX,SPACE
- CALL COUT
- RET
- DOFENCE ENDP
-
- ; SHOW FILE NAME, SIZE (DI POINTS TO INFO)
- ;
- SHOW PROC NEAR
- PUSH DI
- MOV CX,8
- SHOWNAME: ;SHOW FILE NAME
- MOV AL,ES:[DI+9] ;GET CHAR.
- CMP AL,'.'
- JE GOTDOT ;DOT MEANS END OF NAME
- CMP AL,0
- JE SHOWEXT ;SO DOES NULL
- CALL COUT ;SHOW CHAR.
- INC DI ;BUMP POINTER
- DEC CX ;DEC COUNT
- JMP SHOWNAME ;LOOP
- GOTDOT: PUSH AX ;FOUND END OF NAME, UNUSED COUNT IN CX
- CALL SPOUT ;WRITE CX SPACES
- POP AX
- CALL COUT ;NOW WRITE DOT
- INC DI ;POINT PAST DOT
- JMP SHORT SHOW3
- SHOWEXT: INC CX ;HAVE NO EXTENSION
- CALL SPOUT ;PAD OUT NAME FIELD
- SHOW3: MOV CX,3 ;PREPARE TO SHOW EXTENSION (3 CHARS.)
- SHOW4: MOV AL,ES:[DI+9] ;GET CHAR.
- CMP AL,0
- JE SHOW5 ;DONE IF NULL
- CALL COUT ;SHOW CHAR.
- INC DI ;BUMP POINTER
- LOOP SHOW4 ;LOOP
- SHOW5: CALL SPOUT ;PRINT A SPACE
- SHOW6: POP DI ;POINT TO START OF INFO AGAIN
- MOV AL,ES:[DI] ;GET FILE ATTRIBUTE
- AND AL,00010000B ;IS IT A DIRECTORY?
- JZ SHOW7 ;NO.
- CMP BYTE PTR LFLAG,0 ;LONG DISPLAY?
- JE SHOW6A ;NO
- MOV CX,3 ;YES, 3 EXTRA SPACES
- CALL SPOUT
-
- SHOW6A: ;HAVE DIRECTORY
- CALL TYPTX
- DB '<DIR','>'+80H ;SAY IT'S A DIR
- CMP BYTE PTR LFLAG,0 ;IS L FLAG SET?
- JNE SHOW8A ;YES, FINISH UP
- RET ;NO, ALL DONE
-
- SHOW7: ;HAVE FILE, NOT DIR
- MOV AX,ES:[DI+5] ;LSW OF FILE SIZE
- MOV DX,ES:[DI+7] ;MSW OF FILE SIZE
- ADD AX,WORD PTR USED ;ADD LSW OF FILE SIZE TO
- ;LSW OF USED COUNT
- MOV WORD PTR USED,AX
- ADC WORD PTR USED+2,DX ;NOW ADD MSW
- CMP BYTE PTR LFLAG,0 ;L FLAG SET?
- JNE SHOW8 ;YES, LONG DISPLAY
- MOV AX,ES:[DI+5] ;SHORT DISPLAY, GET LSW FILE SIZE
- CALL MAKEK ;CONVERT TO KBYTES
- MOV AL,SPACE ;WITH LEADING SPACES,
- MOV CX,4 ;AND FIELD WIDTH = 4,
- CALL DECOUT ;SHOW FILE SIZE
- MOV AL,'K'
- CALL COUT ;SHOW LETTER K
- RET ;DONE
-
- SHOW8: MOV AX,ES:[DI+5] ;LONG DISPLAY
- PUSH SI ;MOVE SIZE TO DI:SI
- MOV SI,AX
- MOV AX,ES:[DI+7]
- PUSH DI
- MOV DI,AX
- MOV AL,SPACE ;WITH LEADING SPACES,
- CALL PRINTDD ;SHOW FILE SIZE IN BYTES
- POP DI
- POP SI
- SHOW8A:
- MOV CX,2
- CALL SPOUT ;PRINT 2 SPACES
- MOV AX,ES:[DI+3] ;GET PACKED DATE
- CALL PRTDTE ;SHOW IT
- MOV CX,2
- CALL SPOUT ;PRINT 2 SPACES
- MOV AX,ES:[DI+1] ;GET PACKED TIME
- CALL PRTTME ;SHOW IT
- RET ;DONE
- SHOW ENDP
-
- ; SUBROUTINE - WRITES CX SPACES TO SCREEN
-
- SPOUT PROC NEAR
- JCXZ SPOUT1
- MOV AL,SPACE
- CALL COUT
- DEC CX
- JMP SPOUT
- SPOUT1: RET
- SPOUT ENDP
-
- ; SUBROUTINE - PAUSES AT END OF SCREEN
-
- WAITCR PROC NEAR
- PRINT MSG3 ;PROMPT USER FOR OK TO SHOW NEXT SCREEN
- CALL CLRCO ;CLEAR TYPE-AHEAD
- CALL CIN ;GET A CHAR.
- CALL CLRSCR ;CLEAR SCREEN
- RET
- WAITCR ENDP
-
- ; ROUTINE TO CLEAR SCREEN, HOME CURSOR:
- ; (MAY HAVE TO CHANGE FOR NON-IBM MACHINES)
-
- CLRSCR PROC NEAR
- PUSH BX
- IF IBM
- MOV DX,0
- CALL MOVEXY ;MOVE TO HOME POSITION
- MOV AL,BYTE PTR DATA:VMODE ;GET CURRENT VIDEO MODE
- MOV AH,0
- INT BIOS ;RESET MODE (CLEARS SCREEN)
- ELSE
- MOV AL,FF ;NON-IBM CLEAR SCREEN
- CALL COUT ;USE FF (WILL WORK ON MOST TERMINALS)
- ENDIF
- POP BX
- RET
- CLRSCR ENDP
-
- MOVEXY PROC NEAR ;MOVE TO ROW (DH) AND COLUMN (DL)
- MOV AH,2
- MOV BH,BYTE PTR VPAGE ;VIDEO PAGE #
- MOV BL,0 ;COLOR (DON'T CHANGE)
- INT BIOS ;MOVE CURSOR
- RET
- MOVEXY ENDP
-
- ;**************************************************
- ; DISPLAY NUMBER OF FILES, SPACE USED, SPACE FREE *
- ;**************************************************
- SHOW_INFO PROC NEAR
- MOV BX,WORD PTR NUMFILES ;GET NUMBER OF FILES
- MOV AL,0 ;SUPPRESS LEADING 0'S
- MOV CX,5 ;FIELD WIDTH = 5
- CALL DECOUT ;SHOW # FILES
- CALL TYPTX
- DB ' files, using',SPACE+80H
- CMP BYTE PTR LFLAG,0 ;L FLAG SET?
- JE INFO1 ;NO, SHORT DISPLAY
- MOV DI,WORD PTR USED+2
- MOV SI,WORD PTR USED ;GET SPACE USED IN SI:DI
- MOV AL,0 ;SUPPRESS LEADING 0'S
- CALL PRINTDD ;SHOW SPACE USED
- CALL TYPTX
- DB ' bytes ','('+200Q
- JMP SHORT INFO2
- INFO1: ;SHORT DISPLAY
- MOV AX,WORD PTR USED
- MOV DX,WORD PTR USED+2 ;GET AMT. USED IN DX:AX
- CALL MAKEK ;CONVERT TO K
- MOV AL,0 ;SUPPRESS LEADING 0'S
- MOV CX,5 ;FIELD WIDTH = 5
- CALL DECOUT ;SHOW AMT. USED
- MOV AL,'K'
- CALL COUT ;SHOW LETTER K
- INFO2:
- MOV AH,CURRENT_DISK
- INT DOS ;GET CURRENT DISK
- PUSH AX ;SAVE IT
- MOV DL,BYTE PTR DRIVE ;DL = DRIVE WE SPECIFIED
- CMP DL,0 ;CURRENT DISK?
- JE NOCHANGE ;YES, NO NEED TO CHANGE
- INC AL
- CMP AL,DL ;SAME AS CURRENT DISK?
- JE NOCHANGE ;YES, NO NEED TO CHANGE
- DEC DL ;MAKE 0=A, ETC.
- MOV AH,SELECT_DISK
- INT DOS ;SELECT DISK
- NOCHANGE:
- MOV DL,0 ;NOW USING CURRENT DISK,
- MOV AH,GET_FREE_SPACE
- INT DOS ;GET FREE SPACE
- MUL BX ;COMPUTE # SECTORS FREE
- PUSH DX ;SAVE HI WORD
- MUL CX ;MULTIPLY LO WORD OF SECTOR COUNT
- ;BY BYTES/SECTOR
- MOV LOSIZE,AX ;SAVE LO WORD OF FREE SPACE
- POP BX ;GET HI WORD OF SECTOR COUNT
- PUSH DX ;SAVE CARRY FROM LO WORD MULT.
- MOV AX,BX ;MULTIPLICAND IN AX
- MUL CX ;MULTIPLY HI WORD OF SECTOR COUNT
- ;TIMES BYTES/SECTOR
- POP BX ;GET CARRY FROM LO WORD
- ADD AX,BX ;ADD IT
- MOV DX,AX ;DX = HI WORD OF FREE SPACE
- MOV AX,LOSIZE ;AX = LO WORD OF FREE SPACE
- CMP BYTE PTR LFLAG,0 ;L FLAG SET?
- JE INFO3 ;NO, SHORT DISPLAY
- MOV DI,DX ;LONG DISPLAY,
- MOV SI,AX ;MOVE AMT. FREE TO DI:SI
- MOV AL,0 ;SUPPRESS LEADING 0'S
- CALL PRINTDD ;SHOW AMT. FREE
- CALL TYPTX
- DB ' bytes free',')'+200Q
- JMP SHORT INFO4
- INFO3: ;SHORT DISPLAY
- MOV CX,K ;CX = 1 K
- DIV CX ;DIVIDE TO GET KBYTES FREE
- MOV BX,AX ;SAVE IT
- MOV AL,SPACE
- CALL COUT ;WRITE SPACE
- MOV AL,'('
- CALL COUT ;WRITE PAREN
- MOV AL,0 ;MEANS NO LEADING 0'S
- MOV CX,5 ;5 DIGITS MAX.
- CALL DECOUT ;SHOW SPACE FREE
- CALL TYPTX
- DB 'K free',')'+80H
- INFO4:
- CALL CRLF ;SHOW CR/LF
- POP DX
- MOV AH,SELECT_DISK ;RESET DEFAULT DISK
- INT DOS
- RET ;DONE
- SHOW_INFO ENDP
-
- ; MAKEK = TAKE QUAD # IN DX:AX, CONVERT TO K IN BX
-
- MAKEK PROC NEAR
- MOV BX,K
- DIV BX ;DIVIDE TO GET SIZE IN K
- MOV BX,AX ;QUOTIENT IN BX
- CMP DX,0 ;MODULUS>0?
- JE NOROUND
- INC BX ;IF SO, ROUND UP
- NOROUND:
- RET
- MAKEK ENDP
-
- ; The following two routines are adapted from SDIR Version
- ; 2.4, by Ted Reuss (modified from a program by John Chapman), on
- ; PC-SIG Volume 185.
-
- SUBTTL PRINT DATE, TIME & # FILES ROUTINES
- PAGE
-
- ; PC-DOS packed date <yyyyyyym mmmddddd>
- P_DTE RECORD P_YR:7,P_MO:4,P_DY:5
- ; PC-DOS packed time <hhhhhmmm mmmsssss>
- P_TME RECORD P_HR:5,P_MI:6,P_2S:5
-
- PRTDTE PROC NEAR ;Print packed date in AX as MM/DD/YY
- OR AX,AX
- JNZ K1 ;If date <> 0
- MOV CX,8
- CALL SPOUT ;Print 8 spaces
- RET
- K1: PUSH AX
- AND AX,MASK P_MO ;Mask the month,
- MOV CL,P_MO ; set shift count,
- SHR AX,CL ; right justify, &
- CALL PRTBCD ; print it.
- MOV AX,'/'
- CALL COUT
- POP AX
- PUSH AX
- AND AX,MASK P_DY ;Mask the day &
- CALL PRTBCD ; print it.
- MOV AX,'/'
- CALL COUT
- POP AX
- AND AX,MASK P_YR ;Mask the year,
- MOV CL,P_YR ; set shift count,
- SHR AX,CL ; right justify,
- ADD AX,80 ; add in year bias, &
- ; print it.
- PRTBCD: AAM ;Convert AL to BCD
- OR AX,'00' ;Convert to ASCII
- PUSH AX
- MOV AL,AH
- CALL COUT ;High order digit
- POP AX
- CALL COUT ;Low order digit
- RET
- PRTDTE ENDP
-
- PRTTME PROC NEAR ;Print packed time in AX as HH:MM
- OR AX,AX
- JNZ L1 ;if date<>0
- MOV CX,5
- CALL SPOUT ;Print 5 spaces
- RET
- L1: PUSH AX
- AND AX,MASK P_HR ;Mask the hours,
- MOV CL,P_HR ; set shift count,
- SHR AX,CL ; right justify, &
- CALL PRTBCD ; print it.
- MOV AX,':'
- CALL COUT
- POP AX
- AND AX,MASK P_MI ;Mask the minutes,
- MOV CL,P_MI ; set shift count,
- SHR AX,CL ; right justify, &
- CALL PRTBCD ; print it.
- RET
- PRTTME ENDP
-
- CODE ENDS
- END ENTRY
-